package com.platform.mall.service.impl;

import cn.hutool.core.map.MapUtil;
import com.google.common.collect.Maps;
import com.platform.mall.common.exception.BizException;
import com.platform.mall.common.result.Result;
import com.platform.mall.security.token.SysUserAuthenticationToken;
import com.platform.mall.security.token.UserMemberAuthenticationToken;
import com.platform.mall.security.userdetails.member.MemberUserDetails;
import com.platform.mall.security.userdetails.user.SysUserDetails;
import com.platform.mall.service.AuthService;
import com.platform.mall.utils.JWTokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Map;


@Slf4j
@Service
@AllArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final RedisTemplate redisTemplate;
    private final AuthenticationManager authenticationManager;
    @Qualifier("userMemberDetailsService")
    private final UserDetailsService userMemberDetailsService;
    @Qualifier("sysUserDetailsService")
    private final UserDetailsService sysUserDetailsService;
    private final JWTokenUtil jwTokenUtil;

    @Override
    public Result logout() {
        return null;
    }

    @Override
    public Result login(Map<String, String> model) {
        //不同的用户类型使用不同的登陆方式
        String token = "";
        String userType = MapUtil.getStr(model, "user_type", "");
        String username = MapUtil.getStr(model, "username", null);
        String password = MapUtil.getStr(model, "password", null);
        Assert.notNull(username, "用户名不能为null");
        Assert.notNull(password, "密码不能为null");
        UserDetails userDetails = null;
        if (userType.equals(MemberUserDetails.USER_TYPE)) {
            login(new UserMemberAuthenticationToken(username, password));
            userDetails = userMemberDetailsService.loadUserByUsername(username);
            token = jwTokenUtil.generateToken(userDetails);
            log.info("member[{}]登陆成功", username);
            Map<String, Object> loginVO = Maps.newHashMap();
            loginVO.put("token", token);
            loginVO.put("userId",((MemberUserDetails) userDetails).getMemberId());
            return Result.success(loginVO);
        } else if (userType.equals(SysUserDetails.USER_TYPE)) {
            login(new SysUserAuthenticationToken(username, password));
            userDetails = sysUserDetailsService.loadUserByUsername(username);
            token = jwTokenUtil.generateToken(userDetails);
            log.info("sysUser[{}]登陆成功", username);
            Map<String, Object> loginVO = Maps.newHashMap();
            loginVO.put("token", token);
            loginVO.put("userId",((MemberUserDetails) userDetails).getMemberId());
            return Result.success(loginVO);
        } else {
            log.error("userType[{}]参数错误", userType);
            //type参数错误
            throw new BizException(String.format("userType[{}]参数错误", userType));
        }
    }

    /**
     * 校验账号密码并进行登陆
     *
     * @param upToken
     */
    private void login(UsernamePasswordAuthenticationToken upToken) {
        //验证
        Authentication authentication = authenticationManager.authenticate(upToken);
        //将用户信息保存到SecurityContextHolder=登陆
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }


}
